'use strict';

const Controller = require('egg').Controller;
const fs = require('fs');
const path = require('path');
//故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
//管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
const dayjs = require('dayjs');
const { initDomNode, insertNode, render, XMl_render } = require("../utils/common")
const compressing = require("compressing")
const cheerio = require('cheerio');
const http = require('http');



class FileController extends Controller {
    // 文件上传
    async upload_file() {
        const stream = await this.ctx.getFileStream();
        console.log('-----------获取数据 start--------------');
        console.log(stream.fields);
        console.log('-----------获取数据 end--------------');
        // 基础的目录
        const uplaodBasePath = 'app/public/uploads';
        // 生成文件名
        const filename = `${Date.now()}${Number.parseInt(
            Math.random() * 1000,
        )}${path.extname(stream.filename).toLocaleLowerCase()}`;
        // 生成文件夹
        const dirname = dayjs(Date.now()).format('YYYY/MM/DD'); 
        this.mkdirsSync(path.join(uplaodBasePath, dirname));
        // 生成写入路径
        const target = path.join(uplaodBasePath, dirname, filename);
        // 写入流
        const writeStream = fs.createWriteStream(target);
        try {
            //异步把文件流 写入
            await awaitWriteStream(stream.pipe(writeStream));
            this.ctx.body = path.join('/public/uploads', dirname, filename).replace(/\\/g, "/")
        } catch (err) {
            //如果出现错误，关闭管道
            await sendToWormhole(stream);
            this.ctx.body = "error"
        }

    }

    async downloadPage() {
        const { ctx } = this;
        let pageName = ctx.query.pageName;
        // ctx.redirect(ctx.request.header.host + '/static/uploadsHtmlTemp/' + pageName + '.zip')  
        const results = await this.app.mysql.query(`select a.*,b.tag,b.type as tag_type from 
        (
          select a.pageTitle,a.javaScriptOption,b.* from magic_page as a 
          LEFT JOIN magic_page_view as b 
          on a.pageName = b.view_name
          where a.pageName = '${pageName}'
        ) as a
        LEFT JOIN magic_tag as b
        on a.magic_tag = b.id ORDER BY a.id asc`);
        const { pageTitle, javaScriptOption } = results[0]
        const nodes = initDomNode(results);
        for (let item of nodes) {
            if (item.magic_page_components_name) {
                const components_results = await this.app.mysql.query(`
            select a.*,b.tag,b.type as tag_type from magic_page_components as a
              LEFT JOIN magic_tag as b
              on a.magic_tag = b.id
              where a.component_name = '${item.magic_page_components_name}'`);
                const components_node = initDomNode(components_results);
                item.children = insertNode(item.children, components_node)
            }
        }
        let { html, css_file } = render(nodes, { pageTitle })

        // 基础的目录
        const uplaodBasePath = 'app/public/uploadsHtmlTemp';
        // 生成文件夹
        const dirname = pageName;
 
        
        this.mkdirsSync(path.join(uplaodBasePath, dirname));
        const buffer= fs.readFileSync(path.join("app/public/css", "common.css"))  
        await this.fs_writeFile(path.join(uplaodBasePath, dirname, "index.css"), String(buffer) + css_file);
        
        const $ = cheerio.load(html)
        // 生成图片文件夹目录
        this.mkdirsSync(path.join(uplaodBasePath + "/" +  dirname, "image"));
        // 替换图片并下载
        for(let i = 0 ; i < $("img").length ; i++){
            console.log($("img").eq(i).attr("src"))
            let name = $("img").eq(i).attr("src").split("/").pop()
            // 通过链接下载文件到指定目录 /1592387637461742.png
            await this.downLoad($("img").eq(i).attr("src"), path.join(uplaodBasePath + "/" +  dirname, "image") + '/' + name )
            html = html.replace( $("img").eq(i).attr("src"), "./image/" +name )

        }
        await this.fs_writeFile(path.join(uplaodBasePath, dirname, "index.html"), html.replace('<link rel="stylesheet" type="text/css" href="static/css/common.css"   class=""   />' , '<link rel="stylesheet" type="text/css" href="./index.css"   class=""   />' ) );
        await compressing.zip.compressDir(path.join(uplaodBasePath, dirname), path.join(uplaodBasePath, dirname + '.zip'))
        // this.deleteFolder(path.join(uplaodBasePath, dirname))
        // 文件下载
        ctx.attachment(dirname + '.zip');
        ctx.set('Content-Type', 'application/octet-stream');
        ctx.body = fs.createReadStream(path.join(uplaodBasePath, dirname + '.zip'));
 
    }
    // 文件写入
    fs_writeFile(path, data){
        return (new Promise(function(resolve, reject){
            fs.writeFile(path, data, 'utf8', function (err) { 
                resolve()
            })
        }))
    }
    // 创建文件夹
     mkdirsSync(dirname) {
        if (fs.existsSync(dirname)) {
            return true;
        } else {
            if (this.mkdirsSync(path.dirname(dirname))) {
                fs.mkdirSync(dirname);
                return true;
            }
        }
    }
    // 删除文件夹
     deleteFolder(path) {
        let files = [];
        if (fs.existsSync(path)) {
            files = fs.readdirSync(path);
            files.forEach(function (file, index) {
                let curPath = path + "/" + file;
                if (fs.statSync(curPath).isDirectory()) {
                    deleteFolder(curPath);
                } else {
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }
    // 下载文件到本地
     downLoad(url,filePath) {
         
        return (new Promise(function(resolve, reject){
            http.get(url, function(res){
                var imgData = ""; 
                res.setEncoding("binary"); //一定要设置response的编码为binary否则会下载下来的图片打不开
                res.on("data", function(chunk){
                    imgData+=chunk;
                });
                res.on("end", function(){
                    // return false;
                    fs.writeFile(filePath, imgData, "binary", function(err){
                        resolve()
                        if(err){
                            console.log("down fail");
                        }else{
                            console.log("down success");
                        }
                    });
                });
            });
        }))
    } 

}

module.exports = FileController;
